package hikari.instruments;

import com.gooddies.wiring.annotations.Wire;
import com.gooddies.wiring.annotations.WiringComponent;
import hikari.managers.Manager3D;
import hikari.objects3d.Basic3dObject;
import hikari.objects3d.helper_objects.ExtendedEditorCamera;
import hikari.utils.IRenderable;
import org.swig.jirr.ISceneNode;
import org.swig.jirr.vector3df;

/**
 * @author sad
 */
@WiringComponent(singleton = false)
public class CameraObserveInstrument extends HikariInstrument {

    private ExtendedEditorCamera camera;
    private IRenderable renderSurface;
    @Wire
    private Manager3D manager3D;

    protected CameraObserveInstrument() {
    }

    
    
    public CameraObserveInstrument setCamera(ExtendedEditorCamera camera) {
        this.camera = camera;
        return this;
    }

    public CameraObserveInstrument setRenderSurface(IRenderable renderSurface) {
        this.renderSurface = renderSurface;
        return this;
    }

    private void render() {
        if (renderSurface != null) {
            renderSurface.render();
        } else {
            manager3D.render();
        }
    }

    @Override
    public void mouseMove(int x, int y, int dx, int dy, int modifier) {
        if (isWheelDown(modifier)) {
            if (isShiftPressed(modifier)) {
                pan(x, y, dx * 10, dy * 10);
            } else {
                pan(x, y, dx, dy);
            }

        } else if (isLeftMouseDown(modifier) && isRightMouseDown(modifier)) {
            observe(x, y, dx, dy);
        }
    }

    @Override
    public void mouseWheel(int x, int y, int wheel, int modifier) {
        zoom(wheel, modifier);
    }

    protected void observe(int x, int y, int dx, int dy) {
        ISceneNode tCamera = camera != null ? camera : manager3D.getCamera();
        float dY = dx / 5.0f;
        float dX = dy / 5.0f;

        vector3df rotation = tCamera.getRotation();
        rotation.addX(dX);
        rotation.addY(dY);
        tCamera.setRotation(rotation);
        render();
    }

    protected void zoom(int wheel, int modifiers) {
        ISceneNode tCamera = camera != null ? camera : manager3D.getCamera();
        float speed = -wheel;
        if (isShiftPressed(modifiers)) {
            speed *= 10;
        }

        tCamera.moveObjectLocalCoordinates(new vector3df(0, 0, speed));
        render();
    }

    protected void pan(int x, int y, int dx, int dy) {
        ISceneNode tCamera = camera != null ? camera : manager3D.getCamera();
        tCamera.moveObjectLocalCoordinates(new vector3df(-dx / 2.0f, dy / 2.0f, 0));
        render();
    }

    @Override
    public void selectObject(Basic3dObject currentSelection, Basic3dObject newSelection) {
        ExtendedEditorCamera tCamera = camera != null ? camera : manager3D.getCamera();
        if (newSelection != null) {
            tCamera.setRotationCenter(newSelection.getMeshSceneNode());
        } else {
            tCamera.setRotationCenter(tCamera.getSceneManager().getRootSceneNode());
        }
    }
}
